package com.suian.aspect;


import jakarta.servlet.http.HttpServletRequest;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import java.util.Arrays;
import java.util.Objects;

@Aspect
@Component
public class RequestAspect {
    private static final Logger log = LoggerFactory.getLogger(RequestAspect.class);

    //定义切入点：拦截所有Controller
//    @Pointcut("execution(public * com.suian.controller..*.*(..))")
//    @Pointcut("@within(org.springframework.web.bind.annotation.RestController)")
    @Pointcut("@annotation(com.suian.aspect.annotation.RequestLoggable)")
    public void myAspect() {

    }

//    @Around("myAspect()")
    @Around("@annotation(com.suian.aspect.annotation.RequestLoggable)")
    public Object logAround(ProceedingJoinPoint joinPoint) {
        //获取请求信息
        HttpServletRequest request = ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();

        //记录日志信息
        log.info("====== Controller Request Start ======");
        log.info("URL     : {}", request.getRequestURL());
        log.info("HTTP Method : {}", request.getMethod());
        log.info("Class Method : {}.{}", joinPoint.getSignature().getDeclaringTypeName(), joinPoint.getSignature().getName());
        log.info("Args    : {}", Arrays.toString(joinPoint.getArgs()));

        //记录方法执行时间
        long startTime = System.currentTimeMillis();
        Object result;
        try {
            result = joinPoint.proceed();
        } catch (Throwable e) {
            log.error("Controller Error: {}",e.getMessage());
            throw new RuntimeException(e);
        }finally {
            long endTime = System.currentTimeMillis();
            log.info("执行时间：{}ms", endTime - startTime);
        }

        //记录返回结果
        log.info("Return: {}", result != null ? result : "void");
        log.info("====== Controller Request End ======");
        return result;
    }

}
